package graduate.wangyaqi.Exam;

import graduate.wangyaqi.Enum.QuestionType;
import graduate.wangyaqi.ErrorCorrectionQuestions.ErrorCorrectionQuestions;
import graduate.wangyaqi.ErrorCorrectionQuestions.ErrorCorrectionQuestionsService;
import graduate.wangyaqi.FillingQuestions.FillingQuestions;
import graduate.wangyaqi.FillingQuestions.FillingQuestionsService;
import graduate.wangyaqi.Models.ExamData;
import graduate.wangyaqi.Models.ExamResult;
import graduate.wangyaqi.OnlyQuestions.OnlyQuestions;
import graduate.wangyaqi.OnlyQuestions.OnlyQuestionsService;
import graduate.wangyaqi.ProgrammeQuestions.ProgrammeQuestions;
import graduate.wangyaqi.ProgrammeQuestions.ProgrammeQuestionsService;
import graduate.wangyaqi.Service.CmdHelper;
import graduate.wangyaqi.SeveralQuestions.SeveralQuestions;
import graduate.wangyaqi.SeveralQuestions.SeveralQuestionsService;
import graduate.wangyaqi.Taoti.TaotiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping(path="/Exam")
public class ExamController {
    @Autowired
    private ExamService examService;
    @Autowired
    private TaotiService taotiService;
    @Autowired
    private OnlyQuestionsService onlyQuestionsService;
    @Autowired
    private SeveralQuestionsService severalQuestionsService;
    @Autowired
    private FillingQuestionsService fillingQuestionsService;
    @Autowired
    private ErrorCorrectionQuestionsService errorCorrectionQuestionsService;
    @Autowired
    private ProgrammeQuestionsService programmeQuestionsService;

    // 插入exam
    @PostMapping(path="/insert")
    public boolean InsertUser(@RequestBody Exam exam){
        Exam item = examService.findExamByStuIDAndQuestionIDAndTaotiIDAndType(exam.getStuID(),exam.getQuestionID(),exam.getTaotiID(), exam.getType());
        if(item!=null){
            return false;
        }
        if(exam.getAnswer1()==""){
            return false;
        }
        item = new Exam();
        item.setStuID(exam.getStuID());
        item.setQuestionID(exam.getQuestionID());
        item.setTaotiID(exam.getTaotiID());
        item.setType(exam.getType());
        item.setAnswer1(exam.getAnswer1());
        item.setAnswer2(exam.getAnswer2());
        item.setAnswer3(exam.getAnswer3());
        item.setAnswer4(exam.getAnswer4());
        examService.save(item);
        return true;
    }

    // 根据stuid,taotiid,questionid获取exam
    @GetMapping(path="/findExamByStuIDAndqAndQuestionIDAndTaotiID")
    public Exam findExamByStuIDAndqAndQuestionIDAndTaotiID(Long stuID, Long questionID,Long taotaoId, String type){
        return examService.findExamByStuIDAndQuestionIDAndTaotiIDAndType(stuID,questionID,taotaoId, type);
    }

    @GetMapping(path="/all")
    public @ResponseBody Iterable<Exam> getAll() {
        return examService.getAll();
    }

    @GetMapping(path="/findExamByStuIDAndTaotiIDOrderByIdDesc")
    public Exam findFirstByStuIDAndTaotiIDOrderByIdDesc(Long stuId,Long taotaoId){
        return examService.findFirstByStuIDAndTaotiIDOrderByIdDesc(stuId,taotaoId);
    }

    @GetMapping(path="/findExamById")
    public Exam findExamById(long id){
        return examService.findExamById(id);
    }

    @GetMapping(path="/GetLastExam")
    public @ResponseBody ExamResult GetLastExam(Long stuId, Long taotaoId){
        Exam lastExam = examService.findFirstByStuIDAndTaotiIDOrderByIdDesc(stuId,taotaoId);
        if(lastExam == null)
        {
            return getExamResult(taotaoId, 0, QuestionType.Only);
        }
        int allCount = taotiService.findById(taotaoId).get().getCount();
        int count= examService.countAllByStuIDAndTaotiID(stuId, taotaoId);
        if(count>=allCount){
            return new ExamResult("已经全部答题完毕",false);
        }

        return getExamResult(taotaoId,lastExam.getQuestionID(), QuestionType.valueOf(lastExam.getType()));
    }

    @GetMapping(path="/GetNextExam")
    public ExamResult GetNext(Long taotaoId, Long id, String type){
        return getExamResult(taotaoId, id, QuestionType.valueOf(type));
    }

    @GetMapping(path="/GetOnlyResult")
    public int[] getOnlyResult(Long stuid){
        int success = examService.countByStuID(stuid);
        int error = examService.countByStuIDNot(stuid);
        return new int[]{success,error };
    }

    @GetMapping(path="/GetPrevExam")
    public ExamResult GetPrev(Long taotaoId, Long id, String type){
        return getPrevExamResult(taotaoId, id, QuestionType.valueOf(type));
    }

    private ExamResult getExamResult(Long taotaoId, long nowId, QuestionType type) {
        if(type==QuestionType.Only){
            OnlyQuestions only= onlyQuestionsService.getFirstByTaotiIDAndIdIsGreaterThan(taotaoId,nowId);
            if(only!=null){
                return new ExamResult(QuestionType.Only,only.getId(),"",true, only);
            }
            type=QuestionType.Several;
            nowId=0;
        }

        if(type==QuestionType.Several){
            SeveralQuestions several=severalQuestionsService.getFirstByTaotiIDAndIdIsGreaterThan(taotaoId,nowId);
            if (several != null) {
                return new ExamResult(QuestionType.Several,several.getId(),"",true, several);
            }
            type=QuestionType.Filling;
            nowId=0;
        }

        if(type==QuestionType.Filling){
            FillingQuestions filling=fillingQuestionsService.getFirstByTaotiIDAndIdGreaterThan(taotaoId,nowId);
            if(filling!=null){
                return new ExamResult(QuestionType.Filling,filling.getId(),"",true, filling);
            }
            type=QuestionType.Error;
            nowId=0;
        }

        if(type==QuestionType.Error){
            ErrorCorrectionQuestions errorCorrection=errorCorrectionQuestionsService.getFirstByTaotiIDAndIdIsGreaterThan(taotaoId,nowId);
            if(errorCorrection!=null){
                return new ExamResult(QuestionType.Error,errorCorrection.getId(),"",true, errorCorrection);
            }
            type=QuestionType.Programme;
            nowId=0;
        }

        ProgrammeQuestions programme=programmeQuestionsService.getFirstByTaotiIDAndIdIsGreaterThan(taotaoId,nowId);
        if (programme != null) {
            return new ExamResult(QuestionType.Programme,programme.getId(),"",true, programme);
        }
        return null;
    }

    private ExamResult getPrevExamResult(Long taotaoId, long nowId, QuestionType type) {
        if(type==QuestionType.Programme){
            ProgrammeQuestions programme=programmeQuestionsService.getFirstByTaotiIDAndIdIsLessThan(taotaoId,nowId);
            if (programme != null) {
                return new ExamResult(QuestionType.Programme,programme.getId(),"",true, programme);
            }
            type=QuestionType.Error;
            nowId=Integer.MAX_VALUE;
        }
        if(type==QuestionType.Error){
            ErrorCorrectionQuestions errorCorrection=errorCorrectionQuestionsService.getFirstByTaotiIDAndIdLessThan(taotaoId,nowId);
            if(errorCorrection!=null){
                return new ExamResult(QuestionType.Error,errorCorrection.getId(),"",true, errorCorrection);
            }
            type=QuestionType.Filling;
            nowId=Integer.MAX_VALUE;
        }
        if(type==QuestionType.Filling){
            FillingQuestions filling=fillingQuestionsService.getFirstByTaotiIDAndIdIsLessThan(taotaoId,nowId);
            if(filling!=null){
                return new ExamResult(QuestionType.Filling,filling.getId(),"",true, filling);
            }
            type=QuestionType.Several;
            nowId=Integer.MAX_VALUE;
        }
        if(type==QuestionType.Several){
            SeveralQuestions several=severalQuestionsService.getFirstByTaotiIDAndIdIsLessThan(taotaoId,nowId);
            if (several != null) {
                return new ExamResult(QuestionType.Several,several.getId(),"",true, several);
            }
            nowId=Integer.MAX_VALUE;
        }
        OnlyQuestions only= onlyQuestionsService.getFirstByTaotiIDAndIdIsLessThan(taotaoId,nowId);
        if(only!=null){
            return new ExamResult(QuestionType.Only,only.getId(),"",true, only);
        }
        return null;
    }
}
